#include <iostream>
#include <string>
#include <string.h>
#include <functional>
#include <memory>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "protocol.hpp"
#include "socket.hpp"

using namespace std;
using namespace socket_namespace;

// TCP的套接字流程：socket -> 准备服务器的IP和port + connect
// -> 准备数据请求(序列化) -> send

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        cout << "Usage: " << argv[0] << " IP Port" << endl;
        exit(-1);
    }

    string serverip = argv[1];
    uint16_t serverport = stoi(argv[2]);

    socketPtr socketfd = std::make_shared<TCPSocket>();
    // int socketfd = ::socket(AF_INET, SOCK_STREAM, 0);
    // 准备服务器的IP和port + connect
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);
    server.sin_addr.s_addr = inet_addr(serverip.c_str());

    // ::connect(socketfd, (struct sockaddr *)&server, sizeof(server));
    if (!socketfd->buildClientSocket(serverip, serverport))
    {
        std::cerr << "connect error" << std::endl;
        exit(1);
    }

    while (true)
    {
        // 准备数据请求(序列化)
        string line("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
        // cout << "Enter #";
        // getline(cin, line);

        int len = line.size();
        std::string lenstr = std::to_string(len);
        line = lenstr + sepbetweenNumandWord + line + sepbetweenNumandWord;

        // send
        socketfd->Send(line);

        std::string outbuffer;

        // 4. 读取应答，response
        ssize_t n = socketfd->Recv(&outbuffer);
        if (n <= 0)
        {
            break;
        }

        // 5. 报文提取，提取报头和有效载荷
        std::string package = Decode(outbuffer);
        if (package.empty())
        {
            continue;
        }

        usleep(500000);

        cout << package << endl;
    }
    socketfd->close();

    return 0;
}
